package page

import (
	"context"
	// "fmt"
	"strings"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/common/utils/pointy"
	"mall/service/blog/model"
	"mall/service/blog/rpc/internal/svc"
	"mall/service/blog/rpc/internal/utils/errorhandler"
	"mall/service/blog/rpc/types/blog"

	// "github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type GetPageBySlugLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetPageBySlugLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetPageBySlugLogic {
	return &GetPageBySlugLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetPageBySlugLogic) GetPageBySlug(in *blog.BaseIdReq) (*blog.PageInfo, error) {
	if (in.Filter == nil || len(*in.Filter) == 0) && (in.Id == nil || *in.Id == 0) {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	preloadMap, eagerLoadMap := modelx.ParsePreloadAndEagerLoad(in.Preload, in.EagerLoad)
	// logrus.Info(fmt.Sprintf("GetPageBySlug preloadMap: %+v", preloadMap))
	// map[blogPage:[Id Title Slug] blogPageDetail:[ContentHtml]]

	// logrus.Info(fmt.Sprintf("GetPageBySlug eagerLoadMap: %+v", eagerLoadMap))
	// map[blogPage:[blogPageDetail]]

	pageEntityName := model.RpcEntityNames.BlogPage
	if _, ok := model.RpcEntityPreloadMap[pageEntityName]; !ok {
		return &blog.PageInfo{}, nil
	}

	pageRepositoryName := model.RepositoryNames.BlogPage
	columnMap, ok := model.RepositoryPreloadMap[pageRepositoryName]
	if !ok {
		return &blog.PageInfo{}, nil
	}

	var page *model.BlogPage
	if in.Filter != nil && len(*in.Filter) > 0 {
		var selectCols []string
		if preloadFields, ok := preloadMap[pageEntityName]; ok {
			selectCols = modelx.ParseSelectColumns(preloadFields, columnMap)
		}
		selectCols = append(selectCols, model.BlogPageColumns.PostStatus)

		filterMap := modelx.ParseFilter(in.Filter, columnMap)
		// logrus.Info(fmt.Sprintf("GetPageBySlug filterMap: %+v", filterMap))
		// map[post_name:map[equalTo:[terms of use]] post_status:map[equalTo:[1]]]
		if filterMap == nil {
			return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
		}

		if in.Id != nil && *in.Id > 0 {
			filterMap[model.BlogPageColumns.ID] = map[string][]any{
				"equalTo": {*in.Id},
			}
		}

		orderBy := modelx.ParseSorter(in.Sorter, columnMap)
		// logrus.Info(fmt.Sprintf("GetPageBySlug orderBy: %s", orderBy))

		res, _, err := l.svcCtx.Page.GetList(l.ctx, model.M{
			"pageSize": uint64(1),
			"orderBy":  orderBy,
			"select":   strings.Join(selectCols, ","),
		}, -1, filterMap)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(res) == 0 {
			return &blog.PageInfo{}, nil
		}

		page = res[0]
	} else if in.Id != nil && *in.Id > 0 {
		data, err := l.svcCtx.Page.FindOne(l.ctx, *in.Id)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		page = data
	}

	if page == nil {
		return &blog.PageInfo{}, nil
	}

	if page.PostStatus != uint16(globalkey.PostStatusPublish) {
		return &blog.PageInfo{}, nil
	}

	pid := page.ID
	subEntitySettingMap := make(map[string]map[string]*model.ColumnSetting)
	if eagerLoadEntities, ok := eagerLoadMap[pageEntityName]; ok {
		for _, entity := range eagerLoadEntities {
			if entitySettingMap, ok := model.RpcEntityPreloadMap[entity]; ok {
				subEntitySettingMap[entity] = entitySettingMap
			}
		}
	}

	pageDetailEntityName := model.RpcEntityNames.BlogPageDetail
	var content *string
	if _, ok := subEntitySettingMap[pageDetailEntityName]; ok {
		pageDetailRepositoryName := model.RepositoryNames.BlogPageDetail
		subPreloadFields, hasSubPreloadFields := preloadMap[pageDetailEntityName]
		subColumnMap, hasSubColumnMap := model.RepositoryPreloadMap[pageDetailRepositoryName]
		if hasSubPreloadFields && hasSubColumnMap {
			subSelectCols := modelx.ParseSelectColumns(subPreloadFields, subColumnMap)

			subFilterMap := make(map[string]map[string][]any)
			subFilterMap[model.BlogPageDetailColumns.PageID] = map[string][]any{
				"equalTo": {pid},
			}
			list, _, err := l.svcCtx.Page.GetDetailList(l.ctx, model.M{
				"pageSize": uint64(1),
				"select":   strings.Join(subSelectCols, ","),
			}, -1, subFilterMap)
			if err != nil {
				return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
			}

			if len(list) > 0 {
				content = pointy.GetPointer(list[0].PostContent)
			}
		}
	}

	return &blog.PageInfo{
		Id:            pointy.GetPointer(pid),
		AuthorId:      pointy.GetPointer(page.PostAuthorID),
		ParentId:      pointy.GetPointer(page.PostParentID),
		Title:         pointy.GetPointer(page.PostTitle),
		Slug:          pointy.GetPointer(page.PostName),
		Excerpt:       pointy.GetPointer(page.PostExcerpt),
		Uri:           pointy.GetPointer(page.GUID),
		Content:       content,
		Status:        pointy.GetPointer(uint32(page.PostStatus)),
		CommentStatus: pointy.GetPointer(uint32(page.CommentStatus)),
		Sort:          pointy.GetPointer(uint32(page.MenuOrder)),
		CreatedAt:     pointy.GetPointer(modelx.FormatTime(page.PostDate, "")),
		UpdatedAt:     pointy.GetPointer(modelx.FormatTime(page.PostModifiedDate, "")),
		CommentCount:  pointy.GetPointer(uint32(page.CommentCount)),
	}, nil
}
